﻿# Cross-platform compatibility settings
ifeq ($(OS),Windows_NT)
    RM = del /Q
    MKDIR = mkdir
    SHELL = cmd
else
    RM = rm -f
    MKDIR = mkdir -p
endif

# Debug mode control (0: off, 1: show test details)
DEBUG ?= 0

# Terminal color detection
ifneq ($(TERM),)
    ifeq ($(findstring xterm,${TERM}),xterm)
        ENABLE_COLOR = 1
    else ifneq ($(wildcard /proc/$$PPID/exe),)
        ENABLE_COLOR = 1
    endif
endif

# Conditional color definitions
ifeq ($(ENABLE_COLOR),1)
    CYAN   := \033[0;36m
    GREEN  := \033[0;32m
    YELLOW := \033[0;33m
    RED    := \033[0;31m
    RESET  := \033[0m
else
    CYAN   :=
    GREEN  :=
    YELLOW :=
    RED    :=
    RESET  :=
endif

EXERCISE_DIR = ./exercises
TEST_DIR = ./test
BUILD_DIR = ./build

EXERCISES = $(wildcard $(EXERCISE_DIR)/*.c)
EXECUTABLES = $(patsubst $(EXERCISE_DIR)/%.c, $(BUILD_DIR)/%, $(EXERCISES))

CC = gcc
CFLAGS = -Wall -Wextra -std=c99
LDFLAGS = -lm

.PHONY: all clean generate-test-cases test-output save-test-results help

all: $(EXECUTABLES)
	@printf "%b\n" "${GREEN}▶ All targets built successfully${RESET}"
	@$(MAKE) clean

$(BUILD_DIR)/%: $(EXERCISE_DIR)/%.c | $(BUILD_DIR)
	@printf "%b" "${CYAN}🔧 Building $@...${RESET}"
	@$(CC) -o "$@" "$<" $(CFLAGS) $(LDFLAGS) && \
		printf "%b\n" " ${GREEN}✓${RESET}" || \
		(printf "%b\n" " ${RED}✗${RESET}" && exit 1)

$(BUILD_DIR) $(TEST_DIR):
	@$(MKDIR) "$@"

clean:
	@printf "%b\n" "${YELLOW}♻️ Cleaning build artifacts...${RESET}"
	@$(RM) $(EXECUTABLES) 2>/dev/null || true
	@$(RM) $(BUILD_DIR)/*.o 2>/dev/null || true

generate-test-cases: $(EXECUTABLES)
	@printf "%b\n" "${CYAN}📁 Generating test cases...${RESET}"
	@for exe in $(EXECUTABLES); do \
		exercise_name=$$(basename "$$exe"); \
		printf "%b" "${CYAN}⏳ $${exercise_name}.out...${RESET}"; \
		"./$$exe" > "$(TEST_DIR)/$${exercise_name}.out" && \
		printf "%b\n" " ${GREEN}✓${RESET}" || \
		printf "%b\n" " ${RED}✗${RESET}"; \
	done
	@$(MAKE) clean

test-output: $(EXECUTABLES)
	@total=0; \
	passed=0; \
	printf "%b\n" "${CYAN}🚀 Starting test validation...${RESET}"; \
	for exe in $(EXECUTABLES); do \
		exercise_name=$$(basename "$$exe"); \
		test_file="$(TEST_DIR)/$${exercise_name}.out"; \
		total=$$((total+1)); \
		printf "%b" "${CYAN}🔍 Testing $${exercise_name}...${RESET}"; \
		if [ ! -f "$$test_file" ]; then \
			printf "%b\n" " ${RED}✗ (Missing test case)${RESET}"; \
			continue; \
		fi; \
		expected=$$(cat "$$test_file"); \
		actual=$$("./$$exe"); \
		if [ "$$expected" = "$$actual" ]; then \
			printf "%b\n" " ${GREEN}✓ Passed${RESET}"; \
			passed=$$((passed+1)); \
			if [ "$(DEBUG)" -eq 1 ]; then \
				printf "  ${CYAN}[EXPECTED]${RESET}\n%s\n  ${CYAN}[ACTUAL]${RESET}\n%s\n\n" "$$expected" "$$actual"; \
			fi; \
		else \
			printf "%b\n" " ${RED}✗ Failed${RESET}"; \
			if [ "$(DEBUG)" -eq 1 ]; then \
				printf "  ${CYAN}[EXPECTED]${RESET}\n%s\n  ${RED}[ACTUAL]${RESET}\n%s\n\n" "$$expected" "$$actual"; \
			fi; \
		fi; \
	done; \
	printf "\n%b\n" "${CYAN}📊 Results: ${GREEN}$${passed}${RESET}/${CYAN}$${total} tests passed${RESET}"
	@$(MAKE) clean

save-test-results: $(EXECUTABLES)
	@total=0; \
	passed=0; \
	printf "%b\n" "${CYAN}💾 Saving test results...${RESET}"; \
	for exe in $(EXECUTABLES); do \
		exercise_name=$$(basename "$$exe"); \
		test_file="$(TEST_DIR)/$${exercise_name}.out"; \
		total=$$((total+1)); \
		expected=$$(cat "$$test_file"); \
		actual=$$("./$$exe"); \
		[ "$$expected" = "$$actual" ] && passed=$$((passed+1)); \
	done; \
	echo "{\"channel\": \"gitee\",\"courseId\": 1789,\"ext\": \"aaa\",\"name\": \"\",\"score\": $$passed,\"totalScore\": 5}" > "$(BUILD_DIR)/test_results.json"
	@printf "%b\n" "${GREEN}✔ Results saved to $(BUILD_DIR)/test_results.json${RESET}"
	@$(MAKE) clean

help:
	@printf "%b\n" "${CYAN}Usage: make [target] [DEBUG=1]${RESET}"
	@printf "Targets:\n"
	@printf "  all             Build all exercises (default)\n"
	@printf "  clean           Remove build artifacts\n"
	@printf "  generate-test-cases  Generate test files\n"
	@printf "  test-output      Validate solutions (DEBUG=1 for details)\n"
	@printf "  save-test-results Save JSON report\n"
	@printf "  help            Show this help\n"
	@printf "\nOptions:\n"
	@printf "  DEBUG=1         Show detailed test output (for test-output target)\n"